package com.snail.common.core.utils.http;

import cn.hutool.core.collection.CollUtil;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description: Http工具类
 * @Author: Snail
 * @CreateDate: 2024/4/17
 * @Version: V1.0
 */
public class HttpUtils {


    /**
     * POST请求
     *
     * @param url        请求地址
     * @param headers    请求头
     * @param queryParam 请求参数
     * @param body       请求体
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String url, Map<String, String> headers, Map<String, String> queryParam, Map<String, String> body) throws Exception {
        HttpClient httpClient = wrapClient(url);
        HttpPost request = new HttpPost(buildUrl(url, queryParam));
        //请求头
        headers.forEach((k, v) -> {
            request.setHeader(k, v);
        });
        if (CollUtil.isNotEmpty(body)) {
            List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
            body.forEach((k, v) -> {
                nameValuePairList.add(new BasicNameValuePair(k, v));
            });
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
            formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
            request.setEntity(formEntity);
        }
        return httpClient.execute(request);
    }

    private static String buildUrl(String url, Map<String, String> queryParam) {
        if (CollUtil.isEmpty(queryParam)) {
            return url;
        }
        StringBuffer urlBuf = new StringBuffer();
        queryParam.forEach((k, v) -> {
            urlBuf.append("&").append(k).append("=").append(v);
        });
        return url + "?" + urlBuf.substring(1, urlBuf.length());
    }


    private static HttpClient wrapClient(String host) throws Exception {
        HttpClient httpClient = new DefaultHttpClient();
        if (host.startsWith("https://")) {
            sslClient(httpClient);
        }
        return httpClient;
    }

    private static void sslClient(HttpClient httpClient) throws Exception {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(X509Certificate[] xcs, String str) {

                }

                public void checkServerTrusted(X509Certificate[] xcs, String str) {

                }
            };
            ctx.init(null, new TrustManager[]{tm}, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx);
            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            ClientConnectionManager ccm = httpClient.getConnectionManager();
            SchemeRegistry registry = ccm.getSchemeRegistry();
            registry.register(new Scheme("https", 443, ssf));
        } catch (KeyManagementException ex) {
            throw new RuntimeException(ex);
        } catch (NoSuchAlgorithmException ex) {
            throw new RuntimeException(ex);
        }
    }
}
